<template>
    <!-- wrapper -->
    <div class="relative" style="height: 430px">
        <!-- video -->
        <div v-show="props.src" id="room-video" class="h-full"/>
        <!-- cover -->
        <div v-show="!props.src" class="absolute top-0 left-0 w-full h-full flex gap-5 flex-col items-center justify-center">
            <n-icon :size="66">
                <img src="/logo.svg">
            </n-icon>
            <h2 class="text-xl font-bold opacity-80">快去喊房主播放视频吧~</h2>
        </div>
    </div>

</template>

<script setup lang="ts">
import { inject, onMounted, watch } from "vue";
import type { PlayerInst } from "./player.ts";
import Artplayer from "artplayer";
import artplayerPluginControl from "artplayer-plugin-control";
import artplayerPluginDanmuku from "artplayer-plugin-danmuku";
import type { WS } from "@/pages/room/ws/ws.ts";
import { MESSAGE_MAX_LENGTH } from "@/pages/room/constant/validation-constants.ts";

const props = defineProps<{
    src?: string
}>();

const ws = inject("ws") as WS

const emits = defineEmits<{
    (e: 'play'): void
    (e: 'pause'): void
    (e: 'seeked', currentTime: number): void
    (e: 'ratechange', rate: number): void
    (e: 'fullscreen', isFullscreen: boolean): void
}>();

let player: Artplayer | null = null;

watch(() => props.src, (value, oldValue, onCleanup) => {
    if (player) {
        ignore.all = true;
        player.switchUrl(value || "");
    }
}, {
    immediate: true
});

const ignore = {
    all: false,
    play: 0,
    pause: 0,
    seek: 0,
    speed: 0
}

const expose: PlayerInst = {
    play: function (ignoreListener: boolean) {
        if (ignoreListener) {
            ignore.play++;
        }
        return player!!.play();
    },
    pause: function (ignoreListener: boolean) {
        if (ignoreListener) {
            ignore.pause++;
        }
        player?.pause();
    },
    seek: function (time, ignoreListener: boolean) {
        if (player) {
            if (ignoreListener) {
                ignore.seek++;
            }
            player.currentTime = time;
        }
    },
    speed: function (value, ignoreListener: boolean) {
        if (typeof value === "number") {
            if (ignoreListener) {
                ignore.speed++;
            }
            player!!.playbackRate = value;
        }
    },

    danmu(options) {
        player!!.plugins.artplayerPluginDanmuku.emit({
            text: options.text,
            color: options.color
        });
    },

    getSpeed(): number {
        return player!!.playbackRate || 1;
    },
    disableListeners(): void {
        ignore.all = true;
    },
    enableListeners(): void {
        ignore.all = false;
    }
}

defineExpose(expose);

onMounted(() => {
    player = new Artplayer({
        container: "#room-video",
        url: props.src || "",
        fullscreen: true, // 全屏
        flip: true, // 画面翻转
        playbackRate: true, // 视频播放速度,
        aspectRatio: false, // 视频长宽比调整,
        setting: true, // 底部显示设置,
        miniProgressBar: true, // 迷你进度条, 失焦后显示,,
        playsInline: true, // 移动端是否inline方式播放
        quality: [], // 画质列表,
        lock: true, // 移动端显示一个锁定按钮
        fastForward: false, // 在移动端添加长按快进的功能
        autoOrientation: true,

        plugins: [
            artplayerPluginControl(),
            artplayerPluginDanmuku({
                danmuku: [],
                lockTime: 0,
                useWorker: true,
                synchronousPlayback: false, // 同步到播放速度,
                mount: document.createElement("div"), // 界面太窄了, 容不下弹幕的输入框, 弄走它,
                beforeEmit(danmu) {
                    const len = danmu.text.trim().length;
                    if (len < 1 || len > MESSAGE_MAX_LENGTH) {
                        return false;
                    }
                    danmu.mode = undefined;
                    danmu.time = undefined;
                    danmu.color = undefined;
                    danmu.border = undefined;
                    ws.emit("message", {
                        details: {
                            message: danmu.text
                        }
                    });
                    return true;
                }
            })
        ]
    });

    player.on("video:loadedmetadata", function (e) {
        // 视频真正加载出来后再响应用户操作
        ignore.all = false;
        // 视频在加载metadata之后会触发一次seeking事件
        // 房间信息初始化后加载视频、然后同步视频进度（这个操作会强制忽略一次seeking事件），但是加载视频后也会触发一次seeking，就会导致一次无意义的seeking触发然后投递给其他用户
        // 所以这里必须在metadata加载完成后seeking之前, 忽略一次seeking事件
        ignore.seek++;
    });
    player.on("fullscreen", function (e) {
        emits("fullscreen", e);
    });
    player.on("video:play", function () {
        if (ignore.all) {
            return;
        }
        if (ignore.play > 0) {
            ignore.play--;
            return;
        }
        emits("play");
    });
    player.on("video:pause", function () {
        if (ignore.all) {
            return;
        }
        if (ignore.pause > 0) {
            ignore.pause--;
            return;
        }
        emits("pause");
    });
    player.on("video:seeking", function (ev) {
        if (ignore.all) {
            return;
        }
        if (ignore.seek > 0) {
            ignore.seek--;
            return;
        }
        emits("seeked", player!!.currentTime);
    });
    player.on("video:ratechange", function (e) {
        if (ignore.all) {
            return;
        }
        if (ignore.speed > 0) {
            ignore.speed--;
            return;
        }
        emits("ratechange", player!!.playbackRate);
    });
});

</script>

<style scoped>

</style>